package com.audaque.springboot.foshanupload.web.nettydemo.handler;

import cn.hutool.json.JSONUtil;
import com.audaque.springboot.foshanupload.web.nettydemo.pool.MyChannelHandlerPool;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.HashMap;
import java.util.Map;

/**
 *
 */

/**
 * @author zgb
 * @desc ...
 * @date 2023-08-08 20:52:38
 */
//TextWebSocketFrame：消息类型，在调用 channelRead中的acceptInboundMessage方法判断msg是不是SimpleChannelInboundHandler中指定的类型
public class SimpleChannelInboundHandler1 extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    //读空闲事件计数
  public static   Integer readIdleTimes = 0;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("与客户端建立连接，通道开启！");
        //微信登录后加入用户所有群组：添加到channelGroup通道组
        MyChannelHandlerPool.channelGroup.add(ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("与客户端断开连接，通道关闭！");
        //添加到channelGroup 通道组
        MyChannelHandlerPool.channelGroup.remove(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //首次连接是FullHttpRequest，处理参数
        if (null != msg && msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;
            String uri = request.uri();
            Map paramMap = getUrlParams(uri);
            System.out.println("接收到的参数是：" + JSONUtil.toJsonStr(paramMap));
            //如果url包含参数，需要处理
            if (uri.contains("?")) {
                String newUri = uri.substring(0, uri.indexOf("?"));
                System.out.println(newUri);
                request.setUri(newUri);
            }
        }
        //里面是模板模式，会调用channelRead0
        super.channelRead(ctx, msg);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {
        String text = textWebSocketFrame.text();
        //清空计数
        readIdleTimes = 0;
        if ("PING".equals(text)) {
            //心跳
            //回复
            answer(channelHandlerContext);
        } else {
            System.out.println(" 其他信息处理 ... ");
            //正常的TEXT消息类型
            System.out.println("客户端发给服务器数据：" + text);
            //群发：channelGroup就是群组，根据参数选择群组
            sendAllMessage(text);
            //转发：可以自定义map同步channelPool信息，根据参数从map获取指定channel进行发送
        }
    }

    /**
     * 回复
     */
    private void answer(ChannelHandlerContext ctx) {
        //回复
        ctx.writeAndFlush(new TextWebSocketFrame("PONG"));
        System.out.println("回复请求：PONG");
    }

    /**
     * 群发
     *
     * @param message
     */
    private void sendAllMessage(String message) {
        //收到信息后，群发给所有channel
        MyChannelHandlerPool.channelGroup.writeAndFlush(new TextWebSocketFrame(message));
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        EchoInboundHandlerUtils.userEventTriggeredClose(ctx, evt);
        super.userEventTriggered(ctx, evt);
    }

    private static Map getUrlParams(String url) {
        Map<String, String> map = new HashMap<>();
        int i = url.indexOf("?");
        if (i < 0) {
            return map;
        }
        if (url.split("\\u003F").length > 0) {
            String[] arr = url.split("\\u003F")[1].split("&amp;");
            for (String s : arr) {
                String key = s.split("=")[0];
                String value = s.split("=")[1];
                map.put(key, value);
            }
            return map;

        } else {
            return map;
        }
    }
}
